#1 一応TensorFlowのリポジトリは2017年8月くらいに初期コミットがされてますが、この親であるdeeplearn.jsはもっと前から開発がされているようです。
※なんかここから常体になってますが気にしないで下さい※ImageDataの縮小
ユーザーから入力された200x200のCanvasの画像を推論にかけるには28x28に縮小しなければならない。CanvasからはImageDataというオブジェクトが取得してこれが各ピクセルの色データを保持している。
このやり方も情報が少なく、このページが唯一僕が見つけられるページだった。ここのコメントにもあるようにこの回答は少し冗長なやり方をしているので改善したものをjsFiddleにうpしたので参考にしていただきたい。入力用Tensorを作成
ImageDataはプロパティが全て読み取り専用だということで、つまりコンストラクタから生成しなければならないのだが、コンストラクタに指定できる配列のサイズが決まっていることと、型も決まっていることで扱いにくい。このような特性のせいで正規化をする際に小数の格納ができない。
なので最初にtf.fromPixels()を使ってTensorを生成しなければならないのだがここでハマった。tf.fromPixels()はImageDataと1~4のチャンネル数をとる。チャンネル数が4の場合は
[255, 200, 0, 100, 50, 3, 80, 72, 40]:ImageData.data -> [[255, 200, 0, 100], [3, 80, 72, 40]]:Tensor
[255, 200, 0, 100, 50, 3, 80, 72, 40]:ImageData.data -> [[255], [3]]:Tensor
let monodata = [];
for (let i=0, len = imgdata.data.length/4; i < len; i += 1) {
monodata.push(imgdata.data[i*4+3]);
monodata.push(0);
monodata.push(0);
monodata.push(0);
}
let monoimgdata = new ImageData(new Uint8ClampedArray(monodata), 28, 28);
let input = tf.fromPixels(monoimgdata, 1).reshape([1, 28, 28, 1]).cast('float32').div(tf.scalar(255));
#2 この変換はCanvasの塗る色の設定を変えることで不要になるかもしれない。
#3 理由は、この学習データを使った推論の入力Tensorはfloat32ではないといけないと怒られるということと、255で割ると小数が出てくるからということがある。
#4 データは0~255の範囲にあるので255で割る。